using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace HttpCrawler.Engine
{
    public class ConsoleHttpCrawlerEngineLogger : IHttpCrawlerEngineLogger
    {
        private const string MessageFormat = "{0}: {1}.";

        public void DownloadFailure(Uri url, Exception exception)
        {
            var webException = exception as WebException;

            if (webException != null && webException.Response is HttpWebResponse)
            {
                var response = (HttpWebResponse)webException.Response;

                var httpStatus = (int)response.StatusCode;

                WriteUrlMessage(url, String.Format("unexpected HTTP status code: {0}", httpStatus));
            }
            else
            {
                WriteUrlMessage(url, "failed to download");
                WriteError(exception);
            }
        }

        public void DownloadSuccess(Uri url)
        {
            WriteUrlMessage(url, "download successful");
        }

        public void Log(string message)
        {
            Console.WriteLine(message);
        }

        public void ProcessSuccess(IHttpCrawlerContentProcessor processor, HttpCrawlerContent content)
        {
            WriteContentMessage(content, "processed successful");
        }

        public void ProcessFailed(IHttpCrawlerContentProcessor processor, HttpCrawlerContent content, Exception exception)
        {
            WriteContentMessage(content, "failed to process");
            WriteError(exception);
        }

        public void PersistContentSuccess(IHttpCrawlerContentPersister persister, HttpCrawlerContent content)
        {
            WriteContentMessage(content, "persist successful");
        }

        public void PersistContentFailed(IHttpCrawlerContentPersister persister, HttpCrawlerContent content, Exception exception)
        {
            WriteContentMessage(content, "failed to persist");
            WriteError(exception);
        }

        private static void WriteContentMessage(HttpCrawlerContent content, string message)
        {
            WriteMessage(message, GetContentFormattedString(content));
        }

        private static void WriteUrlMessage(Uri url, string message)
        {
            WriteMessage(message, url);
        }

        private static void WriteMessage(string message, object target)
        {
            Console.WriteLine(MessageFormat, message, target);
        }

        private static void WriteError(Exception exception)
        {
            Console.WriteLine("\tError: {0}", exception);
        }

        private static string GetContentFormattedString(HttpCrawlerContent content)
        {
            return string.Format("{0} ({1})", content.RequestUrl, content.MimeType);
        }
    }
}
